home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 330_03 / tskdos.asm < prev    next >
Assembly Source File  |  1990-10-10  |  36KB  |  1,587 lines

  1. ;
  2. ;    --- Version 2.2 90-10-12 10:37 ---
  3. ;
  4. ;    CTask - DOS access module.
  5. ;
  6. ;    Public Domain Software written by
  7. ;        Thomas Wagner
  8. ;        Ferrari electronic Gmbh
  9. ;        Beusselstrasse 27
  10. ;        D-1000 Berlin 21
  11. ;        Germany
  12. ;
  13. ; NOTE: Some routines have been moved to "tsksec.asm" in Version 2.1
  14. ;    to support a minimal secondary kernel.
  15. ;
  16. ;    The support for the critical section interrupt was dropped in
  17. ;    version 2.1. Swapping the DOS variable area eliminates
  18. ;    the need for maintaining critical sections across calls.
  19. ;
  20. ; The DOS interrupt (and the related direct disk I/O interrupts) are
  21. ; not reentrant. Access to DOS thus has to be channelled such that no
  22. ; two tasks use DOS services simultaneously. However, there is one
  23. ; exception to this rule. Whenever DOS is waiting for the keyboard, it
  24. ; issues a special interrupt, INT 28h, to signal that background
  25. ; processing for functions > 0Ch may be performed. This is used in the
  26. ; DOS interface for CTask in the following manner:
  27. ;
  28. ;   A task issuing a DOS interrupt will request one of two resources:
  29. ;   "lower_dos" for functions <= 0C, "upper_dos" for functions > 0C.
  30. ;   If a task gets access to "lower_dos", it will also request the
  31. ;   "upper_dos" resource to lock out other tasks from interrupting.
  32. ;   This "upper_dos" resource is shortly released on each INT 28, and
  33. ;   then immediately reclaimed, with task priority temporarily raised
  34. ;   to the maximum value. The first task waiting to execute a 
  35. ;   function > 0C will thus be scheduled to execute the request, but
  36. ;   the resource will be reassigned to the INT 28 handler as soon as
  37. ;   this request terminates, so the waiting task will not be delayed too
  38. ;   long.
  39. ;
  40. ; There are two additional safety measures which have to be taken to
  41. ; avoid getting into conflicts with other resident background programs,
  42. ; especially the DOS PRINT background spooler:
  43. ;
  44. ;   Before actually executing the request, the status of the DOS in-use
  45. ;   flag is checked. If this flag is set, the task enters a busy waiting
  46. ;   loop, calling the scheduler so that the processor is not tied up.
  47. ;
  48. ; NOTE: The method for checking the status of DOS is described in-depth
  49. ;    in the book "The MS-DOS Encyclopedia" from Microsoft Press, in
  50. ;    the chapter on TSR programming. The logic in this module was
  51. ;    developed without the help of this book, so if you compare
  52. ;    the code here with the routines in the Encyclopedia, you may
  53. ;    notice that not all re-entry conditions are checked here.
  54. ;    According to my experience with debugging TSR's and CTask, the
  55. ;    logic should be sufficient for all but the most obscure TSR's.
  56. ;    If you want to be completely on the safe side, you might consider
  57. ;    adding the more thorough checks listed in the Encyclopedia.
  58. ;
  59. ; CAUTION:    This module is not ROMable, and it can only be
  60. ;        installed in the primary kernel.
  61. ;
  62.     name    tskdos
  63. ;
  64.     include    tsk.mac
  65. ;
  66.     IF    DOS
  67. ;
  68.     .tsk_model
  69. ;
  70.     include    tskdeb.h
  71. ;
  72.     Pubfunc    tsk_install_dos
  73.     Pubfunc    tsk_remove_dos
  74.     Pubfunc    tsk_fatal
  75.     IF    CHECKING
  76.     Pubfunc    tsk_fatal_pmd
  77.     Globext    tsk_set_currdis
  78.     Globext    tsk_set_dualdis
  79.     Globext    tsk_rputc
  80.     Globext    tsk_rputs
  81.     Globext    tsk_vrprintf
  82.     CGlbext    tsk_rprintf
  83.     ENDIF
  84. ;
  85.     public    tsk_emergency_exit
  86. ;
  87.     Globext    create_resource
  88.     Globext    delete_resource
  89.     Globext    request_resource
  90.     Globext    request_cresource
  91.     Globext    release_resource
  92.     Globext    create_flag
  93.     Globext    delete_flag
  94.     Globext    set_flag
  95.     Globext    clear_flag
  96.     Globext    wait_flag_clear
  97.     Globext    yield
  98.     Globext    preempt_off
  99. ;
  100.     Locext    tsk_switch_stack
  101.     Locext    tsk_old_stack
  102.     Locext    tsk_remove_group
  103.     Locext    tsk_kill_group
  104.     Locext    tsk_remove_tasker
  105. ;
  106.     extrn    tsk_instflags: word
  107. ;
  108.     extrn    tsk_glob_rec: byte
  109.     IF    NOT SINGLE_DATA
  110.     extrn    tsk_global: dword
  111.     ENDIF
  112. ;
  113. get_in_use_flag    =    34h    ; DOS-function to get in_use_flag address
  114. get_invars    =    5d06h    ; DOS-function to get DOS-variables area
  115. ;
  116. psp_offset    =    10h-2    ; Offset of current PSP in DOS save area
  117. ;                ; (-2 because we add 2 to the start)
  118. ;
  119. ;    Structure of the start of a PSP, including undocumented fields
  120. ;
  121. psp_record    struc
  122. ;
  123.         dw    ?    ; INT 20
  124.         dw    ?    ; alloc block end
  125.         db    ?    ; reserved
  126.         db    5 dup(?) ; system call
  127. psp_exit_addr    dd    ?    ; exit routine address
  128. psp_ctlc_addr    dd    ?    ; control C routine address
  129. psp_cerr_addr    dd    ?    ; critical error routine address
  130. parent_psp    dw    ?    ; PSP of parent process
  131.         db    20 dup(?) ; files table
  132. psp_envseg    dw    ?    ; environment segment
  133. psp_ustack    dd    ?    ; ss/sp of caller
  134.         dw    ?    ; file table length
  135.         dd    ?    ; file table pointer
  136.         dd    ?    ; pointer to nested PSP (?)
  137. ;
  138. psp_record    ends
  139. ;
  140. ;
  141. intseg    segment at 0
  142.         org    10h*4
  143. vidoff        dw    ?    ; video interrupt
  144. vidseg        dw    ?
  145.         org    13h*4
  146. diskoff        dw    ?    ; disk i/o interrupt
  147. diskseg        dw    ?
  148.         org    20h*4
  149. termoff        dw    ?    ; program terminate vector
  150. termseg        dw    ?
  151.         org    21h*4
  152. idosoff        dw    ?    ; dos interrupt
  153. idosseg        dw    ?
  154.         org    25h*4
  155. absreadoff    dw    ?    ; absolute disk read
  156. absreadseg    dw    ?
  157.         org    26h*4
  158. abswriteoff    dw    ?    ; absolute disk write
  159. abswriteseg    dw    ?
  160.         org    27h*4
  161. keepoff        dw    ?    ; Terminate but stay resident
  162. keepseg        dw    ?
  163.         org    28h*4
  164. idleoff        dw    ?    ; dos idle interrupt
  165. idleseg        dw    ?
  166.         org    2ah*4
  167. csectoff    dw    ?    ; dos critical section
  168. csectseg    dw    ?
  169.         org    40h*4
  170. fdiskoff    dw    ?    ; redirected floppy disk I/O interrupt
  171. fdiskseg     dw    ?
  172. ;
  173. intseg    ends
  174. ;
  175. ;----------------------------------------------------------------------------
  176. ;
  177. ;    Variables
  178. ;
  179.     .tsk_data
  180. ;
  181. idle_active    db    0            ; Idle-Interrupt active
  182. dos310        db    0        ; DOS version >= 3.10
  183. ;
  184.     IF    TSK_NAMEPAR
  185. udos_name    db    "DOSUPPER",0
  186. ldos_name    db    "DOSLOWER",0
  187. hdio_name    db    "HARDDISK",0
  188. fdio_name    db    "FLEXDISK",0
  189. vid_name    db    "VIDEO",0
  190.     ENDIF
  191. ;
  192. ;
  193. in_error    dd    ?        ; Adress of DOS error-mode-flag
  194. ;
  195. lower_dos    resource <>
  196. upper_dos    resource <>
  197. hdisk_io    resource <>
  198. fdisk_io    resource <>
  199. video        resource <>
  200. ;
  201. vid_flags    dw    ?
  202. i13h_flags    dw    ?
  203. i13f_flags    dw    ?
  204. ;
  205.     .tsk_edata
  206.     .tsk_code
  207. ;
  208. ;---------------------------------------------------------------------------
  209. ;
  210. ;    Original Interrupt-Entries
  211. ;
  212. savvid        label    dword        ; original Video entry
  213. savvidoff    dw    ?
  214. savvidseg    dw    ?
  215. ;
  216. savdisk        label    dword        ; original Disk I/O entry
  217. savdiskoff    dw    ?
  218. savdiskseg    dw    ?
  219. ;
  220. savfdisk     label    dword        ; original Floppy Disk I/O entry
  221. savfdiskoff    dw    ?
  222. savfdiskseg    dw    ?
  223. ;
  224. savtermoff    dw    ?        ; Terminate vector save
  225. savtermseg    dw    ?
  226. ;
  227. savdos        label    dword        ; original DOS-Entry
  228. savdosoff    dw    ?
  229. savdosseg    dw    ?
  230. ;
  231. savidle        label    dword        ; original IDLE-Entry
  232. savidleoff    dw    ?
  233. savidleseg    dw    ?
  234. ;
  235. savcsect    label    dword        ; Critical Section save
  236. savcsectoff    dw    ?
  237. savcsectseg    dw    ?
  238. ;
  239. savabsread    label    dword        ; Absolute Disk Read save
  240. savabsreadoff    dw    ?
  241. savabsreadseg    dw    ?
  242. ;
  243. savabswrite    label    dword        ; Absolute Disk Write save
  244. savabswriteoff    dw    ?
  245. savabswriteseg    dw    ?
  246. ;
  247. savkeepoff    dw    ?        ; Terminate resident vector save
  248. savkeepseg    dw    ?
  249. ;
  250. ;
  251. dos_version    dw    ?        ; DOS version
  252. ;
  253. temp_1        dw    ?
  254. ;
  255. tsk_dgroup    dw    @CTASK_DATA
  256. ;
  257. zero        db    0
  258. ;
  259. calldos    macro
  260.     pushf
  261.     cli
  262.     call    cs:savdos
  263.     endm
  264. ;
  265. ;---------------------------------------------------------------------------
  266. ;
  267. ;    void tsk_install_dos (void)
  268. ;
  269. ;        Install DOS handler
  270. ;
  271. Localfunc tsk_install_dos
  272. ;
  273. ;    create needed resources & flags
  274. ;
  275.     IFDEF    LOAD_DS
  276.     push    ds
  277.     mov    ax,@CTASK_DATA
  278.     mov    ds,ax
  279.     ENDIF
  280. ;
  281.     IF    TSK_NAMEPAR
  282.     callp    create_resource,<<ds,#upper_dos>,<ds,#udos_name>>
  283.     ELSE
  284.     callp    create_resource,<<ds,#upper_dos>>
  285.     ENDIF
  286. ;
  287.     IF    TSK_NAMEPAR
  288.     callp    create_resource,<<ds,#lower_dos>,<ds,#ldos_name>>
  289.     ELSE
  290.     callp    create_resource,<<ds,#lower_dos>>
  291.     ENDIF
  292. ;
  293.     test    tsk_instflags,IFL_DISK
  294.     jz    inst_nodsk1
  295.     IF    TSK_NAMEPAR
  296.     callp    create_resource,<<ds,#hdisk_io>,<ds,#hdio_name>>
  297.     ELSE
  298.     callp    create_resource,<<ds,#hdisk_io>>
  299.     ENDIF
  300. ;
  301.     IF    TSK_NAMEPAR
  302.     callp    create_resource,<<ds,#fdisk_io>,<ds,#fdio_name>>
  303.     ELSE
  304.     callp    create_resource,<<ds,#fdisk_io>>
  305.     ENDIF
  306. ;
  307. inst_nodsk1:
  308.     test    tsk_instflags,IFL_VIDEO
  309.     jz    inst_novid1
  310.     IF    TSK_NAMEPAR
  311.     callp    create_resource,<<ds,#video>,<ds,#vid_name>>
  312.     ELSE
  313.     callp    create_resource,<<ds,#video>>
  314.     ENDIF
  315. ;
  316. inst_novid1:
  317. ;
  318.     mov    tsk_glob_rec.l_swap,0    ; init swap area length to 0
  319. ;
  320. ;    Get the DOS version. Only v